//
//  SimpleNetwork.swift
//  SimpleNetwork
//
//  Created by mohen on 15/3/9.
//  Copyright (c) 2015年 mohen. All rights reserved.
//

import Foundation

///  定义常用的网络访问方式
public enum HTTPMethod: String {
    case GET = "GET"
    case POST = "POST"
}

public class SimpleNetwork {
    
    // 类属性， 跟对象无关
    static let errorDomain = "com.baidu.error"
    
    // 定义闭包的类型
    
    public typealias Completion = (result: AnyObject?, error: NSError?) -> ()
    
    ///  请求 JSON 数据
    ///
    ///  :param: method     HTTP 请求方法
    ///  :param: urlString  urlString
    ///  :param: params     可选参数字典
    ///  :param: completion 完成回调
    public func requestJSON(method: HTTPMethod, _ urlString:String, params: [String: String]?,completion: Completion){
        
        // 实例化网络请求
        if let request = request(method, urlString, params) {
        
            // 访问网络 - 本身的回调方法是异步的
            session?.dataTaskWithRequest(request, completionHandler: { (data, _ , error) -> Void in
                
                // 如果有错误， 直接回调，将网络访问的错误返回
                if error != nil {
                    completion(result: nil, error: error)
                    return
                }
                
                // 反序列化 -> 字典或者数组
                let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil)
                
                // 判断是否反序列化成功
                if json == nil {
                    let error = NSError(domain: SimpleNetwork.errorDomain, code: -1, userInfo: ["error": "反序列化失败了"])
                    completion(result: nil, error: error)
                } else {
                    // 有结果
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        completion(result: json, error: nil)
                    })
                }
                
                
            }).resume()
            
            return
        }
        
        // 如果网络请求没有创建成功，应该生成一个错误，提供给其他的开发者
        /**
        domain: 错误所属领域字符串 com.itheima.error
        code: 如果是复杂的系统，可以自己定义错误编号
        userInfo: 错误信息字典
        */
        let error = NSError(domain: SimpleNetwork.errorDomain, code: -1, userInfo: ["error": "请求建立失败"])
        completion(result: nil, error: error)
    }
    
    
    ///  返回网络访问的请求
    ///
    ///  :param: method    HTTP访问方法
    ///  :param: urlString urlString
    ///  :param: params    参数字典
    ///
    ///  :returns: 可选的网络请求
    func request(method: HTTPMethod, _ urlString: String, _ params: [String: String]?) -> NSURLRequest? {
        
        if urlString.isEmpty {
            return nil
        }
        
        // 记录 urlString, 因为传入的参数是不可变的
        var urlStr = urlString
        var r:NSMutableURLRequest?
        
        if method == HTTPMethod.GET {
            // URL 的参数是拼接在URL中的
            // 1. 生成查询字符串
            let query = queryString(params)
            
            // 2. 如果有拼接参数
            if query != nil {
                urlStr += "?" + query!
            }
            
            // 3. 实例化请求
            r = NSMutableURLRequest(URL: NSURL(string: urlStr)!)
        } else {
            
            // 设置请求体，通过请求体来设置要请求的数据
            if let query = queryString(params) {
                r = NSMutableURLRequest(URL: NSURL(string: urlStr)!)
                
                // 设置请求方式
                r?.HTTPMethod = method.rawValue
                
                // 设置数据体
                r?.HTTPBody = query.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
            }
        }
        
        return r
    }
    
    
    ///  返回拼接好的urlString
    ///
    ///  :param: params 请求参数
    ///
    ///  :returns: 返回字符串
    func queryString(params: [String: String]?) -> String? {
        
        // 0.判断参数
        if params == nil {
            return nil
        }
        
        // 涉及到数组的使用技巧
        // 1. 定义一个数组
        var array = [String]()
        // 2. 遍历字典
        for (k, v) in params! {
            let str = k + "=" + v.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
            //追加内容
            array.append(str)
        }
    
            return join("&", array)
    }
    
    
    ///  初始化函数
    public init() {}
    
    lazy var session: NSURLSession? = {
        
        return NSURLSession.sharedSession()
    }()
    
}

